using System;
using System.Globalization;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace WeatherInformer
{
    public class WeatherInfo
    {
        #region Constants for request
        private const string WeatherProviderUrl = @"http://free.worldweatheronline.com/feed/weather.ashx";
        private const string FormatOfWeatherResponse = "json";
        private const string DaysForWatching = "1";
        private const string UserKeyFromWeatherProvider = "6a20238109111033122311";
        private const int MaxRequestsPerDay = 500;
        private const double MinRequestTimeout = 24 * 60.0 / MaxRequestsPerDay;
        private const double RequestTimeout = 1;

        private const string WeatherProvider2Url = 
                                @"http://xml.weather.co.ua/1.2/forecast/257?dayf=1&userid=Yousite_com_ua&lang=en";
        #endregion

        public string GasPumpingUnitLocation { get; private set; }
        public WeatherConditions Conditions { get; private set; }
        private string UrlForRequest { get; set; }
        private JObject RequestResult;

        public WeatherInfo(string city = "Romny")
        {
            GasPumpingUnitLocation = city;
            SetUrlForRequest();
            Conditions = new WeatherConditions {City = GasPumpingUnitLocation};
            UpdateConditions();
        }

        private void SetUrlForRequest()
        {
            UrlForRequest = string.Format("{0}?q={1}&format={2}&num_of_days={3}&key={4}",
                WeatherProviderUrl,
                GasPumpingUnitLocation,
                FormatOfWeatherResponse,
                DaysForWatching,
                UserKeyFromWeatherProvider
                );
        }

        public void UpdateConditions()
        {
            if (RequestResult != null && (Conditions.Date - DateTime.Now).Minutes < RequestTimeout)
            {
                return;
            }
            try
            {
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(UrlForRequest);
                using (var response = (HttpWebResponse) request.GetResponse())
                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                using (JsonReader reader = new JsonTextReader(sr))
                {
                    var js = new JsonSerializer();
                    RequestResult = (JObject)js.Deserialize(reader);
                }
            }
            catch (Exception ex)
            {
                Conditions.Error = ex.Message;
            }
            SetConditions(RequestResult);
        }

        private void SetConditions(JObject result)
        {
            if (result != null)
            {
                Conditions.Date = DateTime.Now;
                var date = DateTime.ParseExact(
                    result["data"]["current_condition"][0]["observation_time"].ToString(),
                    "h:mm tt", CultureInfo.InvariantCulture);
                Conditions.Time = new TimeSpan(date.Hour, date.Minute, date.Second);
                Conditions.Temperature = Convert.ToDouble(result["data"]["current_condition"][0]["temp_C"].ToString());
                Conditions.Pressure = Convert.ToDouble(result["data"]["current_condition"][0]["pressure"].ToString());
                Conditions.Humidity = Convert.ToDouble(result["data"]["current_condition"][0]["humidity"].ToString());
                if (result["data"]["error"] != null)
                {
                    Conditions.Error = result["data"]["error"][0]["msg"].ToString();
                }
            }
        }
    }
}